﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace Fis.Web.Rules.Book
{
    public class BookRule : DynamicRule
    {
        protected override bool BeforeExecute()
        {
            base.BeforeExecute();
            switch (Paramater["action"].ToString())
            {
                case "create":
                    Create();
                    break;
                case "account":
                    return Account(Paramater["oldAccount"].ToString());                    
                case "update":
                    Update();
                    break;
                case "newyear":
                    NewYearBook();
                    break;
                case "prevbook":
                    ResolvePreviewBook();
                    break;
                case "taxRate":
                    return TaxRateUpdate();
                case "enterprise":
                    return InfoUpdate();
            }

            return false;
        }

        protected bool InfoUpdate()
        {
            var data = Agile.Engine.Utils.ZipUtils.UnZipDataTable(Paramater["data"].ToString());
            var book = Model.QueryTable("TBOOK");
            book.Rows[0].ItemArray = data.Rows[0].ItemArray;
            book.Rows[0]["SINDEXDATE"] = DateTime.Now;
            Model.UpdateTable(book);
            Result["data"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(book);
            return true;
        }

        protected bool TaxRateUpdate()
        {
            var data = Agile.Engine.Utils.ZipUtils.UnZipDataTable(Paramater["data"].ToString());

            foreach (var d in data.AsEnumerable())
            {
                d["SINDEXDATE"] = DateTime.Now;
                d["SBOOKID"] = BookID;
            }

            data.TableName = "TTAXRATE";
            Model.Delete(data.TableName, "1=1");
            Model.UpdateTable(data);

            Result["data"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(data);
            return true;
        }

        #region ==  返回前一年度账套  ==

        public void ResolvePreviewBook()
        {
            var serviceDataContext = Agile.Engine.Data.DataContext.Get("ServiceDataContext");
            //删除当前账套信息
            serviceDataContext.DefaultModel.ExecuteNonQuery(String.Format("DELETE FROM TBOOK WHERE SBOOKID='{0}' AND FYEAR='{1}'", BookID, BookYear));
            //设置上年度账套为默认登录
            serviceDataContext.DefaultModel.ExecuteNonQuery(String.Format("UPDATE  TBOOK SET FDEFAULT='1', SINDEXDATE=GETDATE() WHERE SBOOKID='{0}' AND FYEAR='{1}'", BookID, int.Parse(BookYear) - 1));
            //返回上年度账套缓存
            var realpath = new CommonRule().BookRealPath(BookID, (int.Parse(BookYear) - 1).ToString());
            Result["cache"] = Agile.Engine.Utils.ZipUtils.ZipBase64(Agile.Engine.Utils.IOUtils.ReadStream(realpath));
            Status = 1;
        }
        #endregion


        public void NewYearBook()
        {
            //修改默认账套信息
            CommonRule common = new CommonRule();
            var newYear = (int.Parse(BookYear) + 1).ToString();
            common.SaveCreateBookInfo(BookID, newYear);

            //写入新账套
            var newbook = Agile.Engine.Utils.ZipUtils.UnZipBase64(Paramater["newbook"].ToString());
            var realpath = common.BookRealPath(BookID, newYear);
            Agile.Engine.Utils.IOUtils.WriteStream(newbook, realpath);
            Status = 1;
        }

        public void Update()
        {
            var data = Agile.Engine.Utils.ZipUtils.UnZipDataTable(Paramater["data"].ToString());
            data.Rows[0]["SINDEXDATE"] = DateTime.Now;
            data.TableName = "TBOOK";
            data.AcceptChanges();
            data.Rows[0].SetModified();
            Model.UpdateTable(data);

            Result["data"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(data);
            Status = 1;
        }

        public bool Account(string old)
        {
            //写入帐套
            var resource = Agile.Engine.ObjectContext.GetResource("BookResource");

            var data = Agile.Engine.Utils.ZipUtils.UnZipDataTable(Paramater["data"].ToString());

            var acc = data.Rows[0]["FACCSTRUCT"].ToString().Trim();
            var oldAcc = old.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
            var newAcc = acc.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
            int len = 0, startlen = 0;
            for (var i = 0; i < newAcc.Length; i++)
            {
                var current = int.Parse(newAcc[i]);
                var oldlen = int.Parse(oldAcc[i]);

                startlen += len;
                len += oldlen;

                if (current == oldlen)
                {
                    continue;
                }
                else if (current > oldlen)
                {
                    var update = resource.Format("accstruct_update", new string('0', current - oldlen), startlen, len);
                    Model.ExecuteNonQuery(update);
                }
                else
                {
                    throw new Exception("会计科目结构修改时不能减少级次中的长度");
                }
            }

            return InfoUpdate();

        }

        public void Create()
        {
            CommonRule common = new CommonRule();

            //写入帐套
            var data = Agile.Engine.Utils.ZipUtils.UnZipDataTable(Paramater["data"].ToString());

            data.Rows[0]["SINDEXDATE"] = DateTime.Now;
            data.Rows[0]["SBOOKID"] = BookID;

            var book = Agile.Engine.Utils.ZipUtils.UnZipBase64(Paramater["cache"].ToString());
            var startime = Agile.Engine.Utils.DataUtils.Parse(DateTime.Now, data.Rows[0]["FBOOKSTARTIME"]);

            var realpath = common.BookRealPath(Paramater["SBOOKID"].ToString(), startime.Year.ToString());
            Agile.Engine.Utils.IOUtils.CreateDirectory(realpath);
            try
            {
                Agile.Engine.Utils.IOUtils.WriteStream(book, realpath);
            }
            catch
            {
                throw new Exception("其他人正在操作，请稍候重试");
            }

            common.SaveCreateBookInfo(Paramater["SBOOKID"].ToString(), startime.Year.ToString());
            var da = new Agile.Engine.Data.DataAccess() { Context = Agile.Engine.Data.DataContext.Get("BookDataContext"), TableName = "TBOOK" };
            common.SwitchConnection(da.Context, BookID, startime.Year.ToString());
            da.Update(data.Rows[0]);

            Status = 1;
        }
    }
}
